package bma.common.netty.thrift.core;

import java.util.concurrent.Executor;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.transport.TTransport;

import bma.common.langutil.concurrent.RapidUpdateTimeline;
import bma.common.langutil.concurrent.TimerManager;
import bma.common.langutil.core.ExceptionUtil;
import bma.common.langutil.core.SizeUtil;
import bma.common.langutil.core.SizeUtil.Unit;
import bma.common.netty.thrift.core.NettyThriftTimeout.Timeout;
import bma.common.thrift.TProcessorRouter;
import bma.common.thrift.servicehub.ThriftServiceNode;

public class NettyThriftConfig {

	protected int maxLength = 1024 * 1024;
	protected TProtocolFactory protocolFactory;
	protected Executor executor;
	protected TimerManager timer;
	protected NettyThriftTimeout timeout;

	public TProtocolFactory getProtocolFactory() {
		return protocolFactory;
	}

	public void setProtocolFactory(TProtocolFactory protocolFactory) {
		this.protocolFactory = protocolFactory;
	}

	public int getMaxLength() {
		return maxLength;
	}

	public void setMaxLength(int maxLength) {
		this.maxLength = maxLength;
	}

	public void setFrameSize(String sz) {
		try {
			this.maxLength = (int) SizeUtil.convert(sz, 1024, Unit.B);
		} catch (Exception e) {
			throw ExceptionUtil.throwRuntime(e);
		}
	}

	public Executor getExecutor() {
		return executor;
	}

	public void setExecutor(Executor exector) {
		this.executor = exector;
	}

	public TimerManager getTimer() {
		return timer;
	}

	public void setTimer(TimerManager timer) {
		this.timer = timer;
	}

	public NettyThriftTimeout getTimeout() {
		return timeout;
	}

	public void setTimeout(NettyThriftTimeout timeout) {
		this.timeout = timeout;
	}

	public TProcessor makeNodeProcessor(ThriftServiceNode node) {
		TProcessorRouter pr = new TProcessorRouter();
		pr.setDefaultModule(node.getDefaultModule());
		pr.setProcessorBeans(node.getServices());

		TProcessorNetty p = new TProcessorNetty();
		p.setExecutor(executor);
		p.setProcessor(pr);

		return p;
	}

	public TProtocol getProtocol(TTransport transport) {
		if (protocolFactory != null)
			return protocolFactory.getProtocol(transport);
		return new TBinaryProtocol(transport);
	}

	public void sureTimeout() {
		if(this.timeout==null) {
			this.timeout = new NettyThriftTimeout();
			this.timeout.setExecutor(executor);
			this.timeout.setTimer(timer);
			this.timeout.setTimeline(new RapidUpdateTimeline<Timeout>());
		}
	}
}
